-
Notifications
You must be signed in to change notification settings - Fork 4.4k
fix: messageTimestamp object <-> int error #2049
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
Reviewer's GuideThis PR fixes failures in saving messages by robustly converting timestamp fields from various object formats to numbers, improves handling when the original message isn’t found during updates, and removes an unnecessary parameter from the session assertion method. Sequence diagram for robust message timestamp conversion during message savesequenceDiagram
participant S as "BaileysStartupService"
participant M as "Message Object"
participant DB as "Database"
S->>M: Receive message with messageTimestamp
alt messageTimestamp is Long
S->>S: Convert using toNumber()
else messageTimestamp is Long-like object
S->>S: Convert using Long.fromValue()
else messageTimestamp is number
S->>S: Use as is
end
S->>DB: Save message with numeric timestamp
Class diagram for updated BaileysStartupService methodsclassDiagram
class BaileysStartupService {
+convertLongToNumber(obj)
+baileysAssertSessions(jids: string[])
// message saving logic now robustly converts timestamps
}
BaileysStartupService --|> ChannelStartupService
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey there - I've reviewed your changes - here's some feedback:
- Consider extracting the repeated Long-like object detection and conversion logic into a shared utility or type guard to reduce duplication and improve maintainability.
- Double-check that removing the
force
parameter frombaileysAssertSessions
won’t break any existing callers, since it alters the method signature and behavior.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Consider extracting the repeated Long-like object detection and conversion logic into a shared utility or type guard to reduce duplication and improve maintainability.
- Double-check that removing the `force` parameter from `baileysAssertSessions` won’t break any existing callers, since it alters the method signature and behavior.
## Individual Comments
### Comment 1
<location> `src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts:4376-4382` </location>
<code_context>
}
+ // Handle Long-like objects that aren't detected by Long.isLong()
+ if (
+ obj &&
+ typeof obj === 'object' &&
+ 'low' in obj &&
+ 'high' in obj &&
+ typeof obj.low === 'number' &&
+ typeof obj.high === 'number'
+ ) {
+ return Long.fromValue(obj).toNumber();
</code_context>
<issue_to_address>
**suggestion:** The Long-like object detection logic is duplicated in multiple places.
Refactor the Long-like object detection and conversion into a shared utility to avoid code duplication and enhance maintainability.
</issue_to_address>
### Comment 2
<location> `src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts:4408-4423` </location>
<code_context>
const contentMsg = message?.message[contentType] as any;
+ // Convert messageTimestamp to number properly
+ let messageTimestamp: number;
+ if (Long.isLong(message.messageTimestamp)) {
+ messageTimestamp = message.messageTimestamp.toNumber();
+ } else if (
+ message.messageTimestamp &&
+ typeof message.messageTimestamp === 'object' &&
+ message.messageTimestamp &&
+ 'low' in message.messageTimestamp &&
+ 'high' in message.messageTimestamp
+ ) {
+ // Handle Long-like objects that aren't detected by Long.isLong()
+ messageTimestamp = Long.fromValue(message.messageTimestamp).toNumber();
+ } else {
+ messageTimestamp = (message.messageTimestamp as number) || Date.now();
+ }
+
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Defaulting to Date.now() if messageTimestamp is falsy may introduce inaccurate timestamps.
Explicitly handle missing timestamps instead of defaulting to Date.now(), such as by assigning null or logging a warning to avoid misleading data.
```suggestion
// Convert messageTimestamp to number properly
let messageTimestamp: number | null;
if (Long.isLong(message.messageTimestamp)) {
messageTimestamp = message.messageTimestamp.toNumber();
} else if (
message.messageTimestamp &&
typeof message.messageTimestamp === 'object' &&
'low' in message.messageTimestamp &&
'high' in message.messageTimestamp
) {
// Handle Long-like objects that aren't detected by Long.isLong()
messageTimestamp = Long.fromValue(message.messageTimestamp).toNumber();
} else if (typeof message.messageTimestamp === 'number') {
messageTimestamp = message.messageTimestamp;
} else {
messageTimestamp = null;
this.logger.warn(`Missing or invalid messageTimestamp for message: ${JSON.stringify(message)}`);
}
```
</issue_to_address>
### Comment 3
<location> `src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts:4607-4609` </location>
<code_context>
const response = await this.client.assertSessions(jids);
return response;
</code_context>
<issue_to_address>
**suggestion (code-quality):** Inline variable that is immediately returned ([`inline-immediately-returned-variable`](https://docs.sourcery.ai/Reference/Rules-and-In-Line-Suggestions/TypeScript/Default-Rules/inline-immediately-returned-variable))
```suggestion
return await this.client.assertSessions(jids);
```
<br/><details><summary>Explanation</summary>Something that we often see in people's code is assigning to a result variable
and then immediately returning it.
Returning the result directly shortens the code and removes an unnecessary
variable, reducing the mental load of reading the function.
Where intermediate variables can be useful is if they then get used as a
parameter or a condition, and the name can act like a comment on what the
variable represents. In the case where you're returning it from a function, the
function name is there to tell you what the result is, so the variable name
is unnecessary.
</details>
</issue_to_address>
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
if ( | ||
obj && | ||
typeof obj === 'object' && | ||
'low' in obj && | ||
'high' in obj && | ||
typeof obj.low === 'number' && | ||
typeof obj.high === 'number' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: The Long-like object detection logic is duplicated in multiple places.
Refactor the Long-like object detection and conversion into a shared utility to avoid code duplication and enhance maintainability.
const response = await this.client.assertSessions(jids); | ||
|
||
return response; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (code-quality): Inline variable that is immediately returned (inline-immediately-returned-variable
)
const response = await this.client.assertSessions(jids); | |
return response; | |
return await this.client.assertSessions(jids); | |
Explanation
Something that we often see in people's code is assigning to a result variableand then immediately returning it.
Returning the result directly shortens the code and removes an unnecessary
variable, reducing the mental load of reading the function.
Where intermediate variables can be useful is if they then get used as a
parameter or a condition, and the name can act like a comment on what the
variable represents. In the case where you're returning it from a function, the
function name is there to tell you what the result is, so the variable name
is unnecessary.
📋 Description
When trying to save any message, the server would fail because messageTimestamp was being received as an object instead of a number.
That caused all instances to have 0 messages and never save a new message.
I have fixed that by just checking if it's an object and handling long-like, then converting correctly.
🧪 Type of Change
🧪 Testing
📸 Screenshots (if applicable)
✅ Checklist
📝 Additional Notes
Summary by Sourcery
Fix messageTimestamp conversion issues by detecting and converting Long and Long-like objects throughout message processing, add safeguards and logging for missing original messages, and update the Baileys session assertion signature.
Bug Fixes:
Enhancements: